﻿using BridgeWeChat.Constant;
using BridgeWeChat.Model;
using BridgeWebSystemLib.Core;
using BridgeWebSystemLib.Core.Net;
using BridgeWebSystemLib.Core.Util;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Memory;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.IO;
using System.Text;
using System.Xml;
using WeChatCommon.BizLogic;
using WeChatCommon.MP;
using WeChatCommon.MP.CommonMessage;
using WeChatCommon.MP.TemplateMessage;
using static BridgeWeChat.Constant.ComEnum;

namespace BridgeWeChatApiService.Controllers
{
    /// <summary>
    /// 微信消息
    /// </summary>
    [ApiController]
    public class WeChatMPController : ControllerBase
    {
        private readonly IMemoryCache _cache;
        public WeChatMPController(IMemoryCache cache)
        {
            _cache = cache;
        }

        /// <summary>
        /// 服务器配置验证
        /// </summary>
        /// <param name="signature"></param>
        /// <param name="timestamp"></param>
        /// <param name="nonce"></param>
        /// <param name="echostr"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpGet("WeChatMessage")]
        public ActionResult WeChatMessage(string signature, string timestamp, string nonce, string echostr)
        {
            string token = HPDHttpContext.AppSettings.Value.WeChatOAConfig.Token;
            if (CheckSignature.Check(signature, timestamp, nonce, token))
            {
                return Content(echostr); //返回随机字符串则表示验证通过
            }
            else
            {
                return Content("");
            }
        }

        /// <summary>
        /// 接收微信消息
        /// </summary>
        [AllowAnonymous]
        [HttpPost("WeChatMessage")]
        public ActionResult WeChatMessage(string msg_signature, string signature, string timestamp, string nonce, string token = null)
        {
            token = HPDHttpContext.AppSettings.Value.WeChatOAConfig.Token;
            if (!CheckSignature.Check(signature, timestamp, nonce, token))
            {
                return Content("参数错误！");
            }
            try
            {
                string encodingAESKey = HPDHttpContext.AppSettings.Value.WeChatOAConfig.EncodingAESKey;
                string appId = HPDHttpContext.AppSettings.Value.WeChatOAConfig.AppID;
                string content = "";

                using (StreamReader reader = new StreamReader(HttpContext.Request.Body))
                {
                    string s = reader.ReadToEndAsync().Result;
                    using (MemoryStream memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(s)))
                    {
                        content = Encoding.UTF8.GetString(memoryStream.ToArray());
                    }
                }
                LogUtil.WriteLog(content);
                XmlDocument document = new XmlDocument();
                if (!string.IsNullOrWhiteSpace(msg_signature)) // 消息加密模式
                {
                    string decryptMsg = string.Empty;
                    var wxBizMsgCrypt = new WXBizMsgCrypt(token, encodingAESKey, appId);
                    int decryptResult = wxBizMsgCrypt.DecryptMsg(msg_signature, timestamp, nonce, content, ref decryptMsg);
                    if (decryptResult == 0 && !string.IsNullOrWhiteSpace(decryptMsg))
                    {
                        LogUtil.WriteLog(decryptMsg);
                        document.LoadXml(decryptMsg);
                        var messageProcess = CommonMessageFactory.CreateMessageProcess(document);
                        string returnResult = messageProcess.ExecuteResult();
                        LogUtil.WriteLog(returnResult);
                        return Content(returnResult);
                    }
                }
                else // 消息未加密处理
                {
                    document.LoadXml(content);
                    var messageProcess = CommonMessageFactory.CreateMessageProcess(document);
                    string returnResult = messageProcess.ExecuteResult();
                    return Content(returnResult);
                }
            }
            catch (Exception ex)
            {
                LogUtil.WriteLog("接收消息并处理和返回相应结果异常：" + ex);
            }
            return Content("");
        }

        /// <summary>
        /// 获得微信AccessToken
        /// </summary>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpGet("GetAccessToken")]
        public string GetAccessToken()
        {
            return _cache.GetOrCreate(CacheKeys.WeChatAccessToken, entry =>
            {
                string appId = HPDHttpContext.AppSettings.Value.WeChatOAConfig.AppID;
                string secret = HPDHttpContext.AppSettings.Value.WeChatOAConfig.AppSecret;
                string strUrl = string.Format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}", appId, secret);
                var token = HttpHelper.Get<WeChatToken>(strUrl);
                entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(token.expires_in - 180);
                return token.access_token;
            });
        }

        /// <summary>
        /// 获得微信关注二维码
        /// </summary>
        /// <returns>Base64字符串图片</returns>
        [AllowAnonymous]
        [HttpPost("GetWeChatFollowQRCode")]
        public string GetWeChatFollowQRCode(WeChatQRCodeRequest request)
        {
            string token = GetAccessToken();
            //创建二维码ticket
            string strUrl = string.Format("https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token={0}", token);
            var data = new
            {
                expire_seconds = 60,
                action_name = "QR_STR_SCENE",
                action_info = new
                {
                    scene = new
                    {
                        scene_str = JsonUtil.JsonSerializeObject(request)
                    }
                }
            };
            string result = HttpHelper.PostJson(strUrl, JsonUtil.JsonSerializeObject(data));
            var objResult = JsonConvert.DeserializeObject(result) as JObject;
            string ticket = (string)objResult["ticket"];
            //通过ticket换取二维码
            string qrCodeUrl = string.Format("https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket={0}", ticket);
            byte[] qrCode = HttpHelper.GetByte(qrCodeUrl);
            //using (FileStream fs = new FileStream("C:\\Users\\houzhipeng\\Desktop\\1.jpg", FileMode.Create, FileAccess.Write))
            //{
            //    fs.Write(qrCode, 0, qrCode.Length);
            //    fs.Flush();
            //    fs.Close();
            //}
            return Convert.ToBase64String(qrCode);
        }



        /// <summary>
        /// 发送模板消息
        /// </summary>
        /// <param name="requestParam"></param>
        [HttpPost("SendWeChatMPTemplateMessage")]
        public string SendWeChatMPTemplateMessage(WeChatTemplateMessageRequest requestParam)
        {
            BaseResponse response = new BaseResponse();
            var msgInfo = RequestHelper.NotnullValidate<WeChatTemplateMessageRequest>(requestParam);
            if (!msgInfo.State)
            {
                response.ResultCode = "-1";
                response.ResultMessage = msgInfo.Message;
                return JsonUtil.JsonSerializeObject(response);
            }



            const string WeChatHttpUrl = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token={0}";
            string token = GetAccessToken();

            string templateId = string.Empty;
            if (!string.IsNullOrEmpty(requestParam.TemplateId))
            {
                templateId = requestParam.TemplateId;
            }
            else
            {
                templateId = GetTemplateId(requestParam.TemplateType);
            }

            string openId = requestParam.OpenId;
            if (string.IsNullOrEmpty(openId))
            {
                var dataAccess = BridgeHttpContext.DataAccess;
                var user = dataAccess.GetByParam<COM_USER>(new { ORGAN_ID = requestParam.OrganId, USER_ID = requestParam.UserId });
                if (user == null)
                {
                    response.ResultCode = "-1";
                    response.ResultMessage = "无此用户";
                    return JsonUtil.JsonSerializeObject(response);
                }
                openId = user.OPEN_ID;
            }

            Data data = new Data();
            data.first = new First() { value = requestParam.First };
            data.keyword1 = new Keyword1 { value = requestParam.Keyword1 };
            data.keyword2 = new Keyword2 { value = requestParam.Keyword2 };
            data.keyword3 = new Keyword3 { value = requestParam.Keyword3 };
            data.keyword4 = new Keyword4 { value = requestParam.Keyword4 };
            data.keyword5 = new Keyword5 { value = requestParam.Keyword5 };
            data.remark = new Remark { value = requestParam.Remark };

            TemplateMessageModel messageModel = new TemplateMessageModel();
            messageModel.touser = openId;
            messageModel.template_id = templateId;
            messageModel.url = requestParam.CallbackUrl;
            messageModel.data = data;

            string jsonData = JsonUtil.JsonSerializeObject(messageModel);
            string url = string.Format(WeChatHttpUrl, token);
            string returnResult = HttpHelper.PostJson(url, jsonData);

            LogUtil.WriteLog(returnResult);

            var tmResponse = JsonUtil.JsonDeserialize<TemplateMessageResponse>(returnResult);
            if (tmResponse.errcode == "0")
            {
                msgInfo = ComMessageUtil.SaveWeChatMPMessage(requestParam, tmResponse.msgid);
                if (!msgInfo.State)
                {
                    response.ResultCode = "-1";
                    response.ResultMessage = msgInfo.Message;
                }
            }
            else
            {
                response.ResultCode = "-1";
                response.ResultMessage = tmResponse.errmsg;
            }
            return JsonUtil.JsonSerializeObject(response);
        }

        private string GetTemplateId(int messageType)
        {
            string templateId = "";
            switch (messageType)
            {
                case (int)模板消息类型.关注消息:
                    templateId = HPDHttpContext.AppSettings.Value.WeChatOAConfig.GZTemplateId;
                    break;
                case (int)模板消息类型.扫码消息:
                    templateId = HPDHttpContext.AppSettings.Value.WeChatOAConfig.SMTemplateId;
                    break;
                case (int)模板消息类型.证照到期提醒:
                    templateId = HPDHttpContext.AppSettings.Value.WeChatOAConfig.ZZDQTemplateId;
                    break;
                case (int)模板消息类型.订单生成通知:
                    templateId = HPDHttpContext.AppSettings.Value.WeChatOAConfig.DDSCTemplateId;
                    break;
                case (int)模板消息类型.订单确认通知:
                    templateId = HPDHttpContext.AppSettings.Value.WeChatOAConfig.DDQRTemplateId;
                    break;
                case (int)模板消息类型.单据审核结果通知:
                    templateId = HPDHttpContext.AppSettings.Value.WeChatOAConfig.DDSHTemplateId;
                    break;
                case (int)模板消息类型.订单配送提醒:
                    templateId = HPDHttpContext.AppSettings.Value.WeChatOAConfig.DDPSTemplateId;
                    break;
                default:
                    break;
            }
            return templateId;
        }
    }
}
